home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / New System Software Extensions / OpenDoc A6 / OpenDoc Parts Framework / OPF / Examples / Clock / Sources / ClockFac.cpp next >
Encoding:
Text File  |  1994-04-21  |  15.0 KB  |  498 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                ClockFac.cpp
  4. //    Release Version:    $ 1.0d1 $
  5. //
  6. //    Author:                Lonnie Millett
  7. //    Creation Date:        3/28/94
  8. //
  9. //    Copyright:    © 1993, 1994 by Apple Computer, Inc., all rights reserved.
  10. //
  11. //========================================================================================
  12.  
  13. #ifndef CLOCKFAC_H
  14. #include "ClockFac.h"
  15. #endif
  16.  
  17. #ifndef CLOCKFRA_H
  18. #include "ClockFra.h"
  19. #endif
  20.  
  21. #ifndef CLOCKPAR_H
  22. #include "ClockPar.h"
  23. #endif
  24.  
  25. // ----- FrameWork Includes -----
  26.  
  27. #ifndef FWUTIL_H
  28. #include <FWUtil.h>
  29. #endif
  30.  
  31. // ----- Graphic Includes -----
  32.  
  33. #ifndef FWOVLSHP_H
  34. #include "FWOvlShp.h"
  35. #endif
  36.  
  37. #ifndef FWTXTSHP_H
  38. #include "FWTxtShp.h"
  39. #endif
  40.  
  41. #ifndef FWLINSHP_H
  42. #include "FWLinShp.h"
  43. #endif
  44.  
  45. #ifndef FWCOLOR_H
  46. #include "FWColor.h"
  47. #endif
  48.  
  49. #ifndef FWRECSHP_H
  50. #include "FWRecShp.h"
  51. #endif
  52.  
  53. // ----- OpenDoc Includes -----
  54.  
  55. #ifndef _FACET_
  56. #include <Facet.h>
  57. #endif
  58.  
  59. #ifndef _FRAME_
  60. #include <Frame.h>
  61. #endif
  62.  
  63. #ifndef _SHAPE_
  64. #include <Shape.h>
  65. #endif
  66.  
  67. #ifndef _DRAGDROP_
  68. #include <DragDrop.h>
  69. #endif
  70.  
  71. #ifndef _DGITMITR_
  72. #include <DgItmItr.h>
  73. #endif
  74.  
  75. #ifndef _STDPROPS_
  76. #include <StdProps.h>
  77. #endif
  78.  
  79. #ifndef _STDTYPES_
  80. #include <StdTypes.h>
  81. #endif
  82.  
  83. #ifndef _STORAGEU_
  84. #include <StorageU.h>
  85. #endif
  86.  
  87. #ifndef _XMPSESSN_
  88. #include <XMPSessM.h>
  89. #endif
  90.  
  91. #ifndef _TRANSLAT_
  92. #include <Translat.h>
  93. #endif
  94.  
  95. // ----- Macintosh Includes -----
  96.  
  97. #if defined(FW_BUILD_MAC) && !defined(__STDTYPES__)
  98. #include <StdTypes.h>
  99. #endif
  100.  
  101. #if defined(FW_BUILD_MAC) && !defined(__QUICKDRAW__)
  102. #include <Quickdraw.h>
  103. #endif
  104.  
  105. #if defined(FW_BUILD_MAC) && !defined(__FONTS__)
  106. #include <Fonts.h>
  107. #endif
  108.  
  109. #if defined(FW_BUILD_MAC) && !defined(__TEXTEDIT__)
  110. #include <TextEdit.h>
  111. #endif
  112.  
  113. #if defined(FW_BUILD_MAC) && !defined(__SCRIPT__)
  114. #include <Script.h>
  115. #endif
  116.  
  117. #if defined(FW_BUILD_MAC) && !defined(__PACKAGES__)
  118. #include <Packages.h>
  119. #endif
  120.  
  121. #if defined(FW_BUILD_MAC) && !defined(__RESOURCES__)
  122. #include <Resources.h>
  123. #endif
  124.  
  125. #if defined(FW_BUILD_MAC) && !defined(__TOOLUTILS__)
  126. #include <ToolUtils.h>
  127. #endif
  128.  
  129. #if defined(FW_BUILD_MAC) && !defined(__OSUTILS__)
  130. #include <OSUtils.h>
  131. #endif
  132.  
  133. #if defined(FW_BUILD_MAC) && !defined(mathRoutinesIncludes)
  134. #include <math routines.h>
  135. #endif
  136.  
  137. #pragma segment cclockfacet
  138.  
  139. //----------------------------------------------------------------------------------------
  140. // The new math libraries for the universal headers have bugs so we're just including
  141. // definitions from the old headers and linking with the old library till the numerics
  142. // guys get the bugs worked out.
  143. //
  144. //extern "C" {
  145. //    extended rint(extended x);
  146. //    extended sin(extended x);
  147. //    extended cos(extended x);
  148. //    extended pi();
  149. //}
  150. //
  151. //#ifndef __FP__
  152. //#include <Fp.h>
  153. //#endif
  154. //----------------------------------------------------------------------------------------
  155.  
  156. //----------------------------------------------------------------------------------------
  157. // CClockFacet::CClockFacet
  158. //----------------------------------------------------------------------------------------
  159. CClockFacet::CClockFacet()
  160. {
  161. }
  162.  
  163. //----------------------------------------------------------------------------------------
  164. // CClockFacet::~CClockFrame
  165. //----------------------------------------------------------------------------------------
  166. CClockFacet::~CClockFacet()
  167. {
  168. }
  169.  
  170. //----------------------------------------------------------------------------------------
  171. // CClockFacet::InitClockFacet
  172. //----------------------------------------------------------------------------------------
  173. void CClockFacet::InitClockFacet(XMPFacet* xmpFacet, CClockFrame* clockFrame)
  174. {
  175.     this->InitFacet(xmpFacet);
  176.     fClockFrame = clockFrame;
  177. }
  178.  
  179. //----------------------------------------------------------------------------------------
  180. // CClockFacet::Draw
  181. //----------------------------------------------------------------------------------------
  182. void CClockFacet::Draw(FW_CGraphicContext *gc)
  183. {
  184.     FW_UNUSED(gc);
  185.  
  186.     unsigned long tickCount = fClockFrame->GetClockPart()->GetLastTime();
  187.     
  188.     if (fClockFrame->GetClockPart()->GetClockType() == kAnalogClock)
  189.     {
  190.         this->DrawClockFace(gc);
  191.         this->DrawClockHands(gc, tickCount);
  192.     }
  193.     else
  194.         UpdateDigitalClock(gc, tickCount);
  195. }
  196.  
  197. //------------------------------------------------------------------------------
  198. // CClockFacet::DragEnter
  199. //------------------------------------------------------------------------------
  200. void CClockFacet::DragEnter(XMPDragItemIterator* dragInfo, const FW_CPoint& where)
  201. {
  202.     XMPTranslation *translate = GetFrame()->GetPart()->GetSession()->GetTranslation();
  203.     XMPType applePICT = translate->GetISOTypeFromPlatformType('PICT', kXMPPlatformDataType);
  204.     XMPType applesnd = translate->GetISOTypeFromPlatformType('snd ', kXMPPlatformDataType);
  205.  
  206.     FW_CFacet::DragEnter(dragInfo, where);
  207.     
  208.     if (!this->GetCanAcceptDrop())
  209.     {
  210.         XMPStorageUnit *dragSU;
  211.         
  212.         for (dragSU = dragInfo->First(); dragSU; dragSU = dragInfo->Next())
  213.             if (dragSU->Exists(kXMPPropContents, applePICT, 0) ||
  214.                     dragSU->Exists(kXMPPropContents, applesnd, 0))
  215.                 this->SetCanAcceptDrop(TRUE);
  216.     }
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. // CClockFacet::DrawClockFace
  221. //----------------------------------------------------------------------------------------
  222. void CClockFacet::DrawClockFace(FW_CGraphicContext *gc)
  223. {
  224.     FW_CPoint centerPoint;
  225.     FW_CPoint newPoint;
  226.     FW_CPoint tickPoint;
  227.     Fixed radius;
  228.     
  229.     FW_CRect clockRect;
  230.     fClockFrame->GetFrameShapeBounds(&clockRect);
  231.     
  232.     centerPoint.x = (clockRect.right - clockRect.left) / 2;
  233.     centerPoint.y = (clockRect.bottom - clockRect.top) / 2;
  234.     radius = centerPoint.x;
  235.  
  236.     FW_COvalShape ovalShape(clockRect);
  237.     
  238.     // ----- Erase under the clock -----
  239.     ovalShape->SetForeColor(FW_kRGBWhite);
  240.     ovalShape->Draw(gc);
  241.     
  242.     PicHandle picHandle = fClockFrame->GetClockPart()->GetBackgroundPICT();
  243.     FW_SPlatformRect qdRect = gc->AsPlatformRect(clockRect);
  244.     if (picHandle)
  245.         ::DrawPicture(picHandle, &qdRect);
  246.     
  247.     // ----- Frame it -----
  248.     ovalShape->SetForeColor(FW_kRGBBlack);
  249.     ovalShape->SetPenSize(ff(2));
  250.     ovalShape->SetShapeFill(FW_kFramed);
  251.     ovalShape->Draw(gc);
  252.  
  253.     // ----- Set the style's font -----
  254.     
  255.     Str255 clockFaceString;
  256.     FW_CAcquireASLMResourceAccess aq;
  257.     ::GetIndString(clockFaceString, kClockPartStrings, kClockFaceString);
  258.  
  259.     FW_CTextShape textShape(clockFaceString[0], (char*)&clockFaceString[1], FW_CPoint(0,0));
  260.     textShape->SetFontName(FW_kHelvetica);        
  261.     textShape->SetFontStyle(FW_kItalic);        
  262.     textShape->SetFontSize(radius / 10);        
  263.  
  264.     FW_CRect textBounds = textShape->GetShapeBounds();    
  265.     FW_CPoint pos(((clockRect.right - clockRect.left) - (textBounds.right - textBounds.left)) / 2, (clockRect.bottom - clockRect.top) / 4);
  266.     textShape->SetPosition(pos);
  267.     textShape->Draw(gc);
  268.     
  269.     // Use the symmetry of the clock face to speed up the calculations for drawing the face
  270.     // We only need to calculate points for 45 degrees of the circle.  The remaining points can
  271.     // be inferred from these points
  272.     short angle = 0;
  273.     short fiveMinute = 0;
  274.  
  275.     while (angle < 45)
  276.     {
  277.         // convert angle to radians
  278.         Fixed radians = ::FixDiv(fl(3.1416) * (90-angle), ff(180));
  279.         Fixed cosRadian = ::Frac2Fix(::FracCos(radians));
  280.         Fixed sinRadian = ::Frac2Fix(::FracSin(radians));
  281.  
  282.         newPoint.x = ::FixMul(radius, cosRadian) + centerPoint.x;
  283.         newPoint.y = ::FixMul(radius, sinRadian) + centerPoint.y;
  284.         
  285.         if (fiveMinute == 0)
  286.         {
  287.             Fixed hourTick = radius - (radius / 10);
  288.             tickPoint.x = ::FixMul(hourTick, cosRadian) + centerPoint.x;
  289.             tickPoint.y = ::FixMul(hourTick, sinRadian) + centerPoint.y;
  290.             fiveMinute = 4;
  291.         }
  292.         else
  293.         {
  294.             Fixed minuteTick = radius - (radius / 20);
  295.             tickPoint.x = ::FixMul(minuteTick, cosRadian) + centerPoint.x;
  296.             tickPoint.y = ::FixMul(minuteTick, sinRadian) + centerPoint.y;
  297.             fiveMinute--;
  298.         }
  299.  
  300.         FW_CLineShape lineShape(FW_CPoint(newPoint.x - ff(1), newPoint.y - ff(1)),
  301.                                 FW_CPoint(tickPoint.x - ff(1), tickPoint.y - ff(1)));
  302.         lineShape->Draw(gc);
  303.         
  304.         lineShape->SetLineStart(FW_CPoint(clockRect.right - newPoint.x, newPoint.y - ff(1)));
  305.         lineShape->SetLineEnd(FW_CPoint(clockRect.right - tickPoint.x, tickPoint.y - ff(1)));
  306.         lineShape->Draw(gc);
  307.  
  308.         lineShape->SetLineStart(FW_CPoint(newPoint.x - ff(1), clockRect.bottom - newPoint.y));
  309.         lineShape->SetLineEnd(FW_CPoint(tickPoint.x - ff(1), clockRect.bottom - tickPoint.y));
  310.         lineShape->Draw(gc);
  311.         
  312.         lineShape->SetLineStart(FW_CPoint(clockRect.right - newPoint.x, clockRect.bottom - newPoint.y));
  313.         lineShape->SetLineEnd(FW_CPoint(clockRect.right - tickPoint.x, clockRect.bottom - tickPoint.y));
  314.         lineShape->Draw(gc);
  315.         
  316.         lineShape->SetLineStart(FW_CPoint(newPoint.y - ff(1), newPoint.x - ff(1)));
  317.         lineShape->SetLineEnd(FW_CPoint(tickPoint.y - ff(1), tickPoint.x - ff(1)));
  318.         lineShape->Draw(gc);
  319.  
  320.         lineShape->SetLineStart(FW_CPoint(clockRect.bottom - newPoint.y, newPoint.x - ff(1)));
  321.         lineShape->SetLineEnd(FW_CPoint(clockRect.bottom - tickPoint.y, tickPoint.x - ff(1)));
  322.         lineShape->Draw(gc);
  323.         
  324.         lineShape->SetLineStart(FW_CPoint(newPoint.y - ff(1), clockRect.right - newPoint.x));
  325.         lineShape->SetLineEnd(FW_CPoint(tickPoint.y - ff(1), clockRect.right - tickPoint.x));
  326.         lineShape->Draw(gc);
  327.  
  328.         lineShape->SetLineStart(FW_CPoint(clockRect.bottom - newPoint.y, clockRect.right - newPoint.x));
  329.         lineShape->SetLineEnd(FW_CPoint(clockRect.bottom - tickPoint.y, clockRect.right - tickPoint.x));
  330.         lineShape->Draw(gc);
  331.  
  332.         angle += 6;
  333.     }
  334. }
  335.  
  336. //----------------------------------------------------------------------------------------
  337. // CClockFacet::DrawClockHands
  338. //----------------------------------------------------------------------------------------
  339. void CClockFacet::DrawClockHands(FW_CGraphicContext *gc, unsigned long tickCount)
  340. {
  341.     FW_CPoint centerPoint;
  342.     DateTimeRec time;
  343.     
  344.     FW_CRect clockRect;
  345.     fClockFrame->GetFrameShapeBounds(&clockRect);
  346.     
  347.     centerPoint.x = (clockRect.right - clockRect.left) / 2;
  348.     centerPoint.y = (clockRect.bottom - clockRect.top) / 2;
  349.     
  350.     ::Secs2Date(tickCount, &time);
  351.     
  352.     this->DrawSecondHand(gc, clockRect, centerPoint, ff(time.second));
  353.     this->DrawMinuteHand(gc, clockRect, centerPoint, ff(time.minute));
  354.     this->DrawHourHand(gc, clockRect, centerPoint, ff(time.hour), ff(time.minute));
  355. }
  356.  
  357. //----------------------------------------------------------------------------------------
  358. // CClockFacet::CalcPoint
  359. //----------------------------------------------------------------------------------------
  360.  
  361. void CClockFacet::CalcPoint(FW_CPoint* point, XMPCoordinate radius, const XMPPoint& center, const FW_CRect& frame, Fixed angle)
  362. {
  363.     point->x = ::FixMul(radius, ::Frac2Fix(::FracSin(angle))) + center.x - ff(1);
  364.     point->y = frame.bottom - (::FixMul(radius, ::Frac2Fix(::FracCos(angle))) + center.y);
  365. }
  366.  
  367. //----------------------------------------------------------------------------------------
  368. // CClockFacet::DrawHourHand
  369. //----------------------------------------------------------------------------------------
  370. void CClockFacet::DrawHourHand(FW_CGraphicContext *gc, 
  371.                                 const FW_CRect& clockRect, 
  372.                                 const FW_CPoint& centerPoint, 
  373.                                 Fixed hour, 
  374.                                 Fixed minute)
  375. {
  376.     FW_CPoint newPoint;
  377.     Fixed hourRadius = centerPoint.x / 2;        // Make the hour hand short and stubby
  378.     
  379.     if (hour > ff(11))
  380.         hour -= ff(12);
  381.     
  382.     // Divide the clock face into degrees.  Hour hand falls on every five minutes or every 30 degrees
  383.     Fixed radians = ::FixDiv(((hour * 30) + (minute / 2)), ::FixDiv(ff(180), fl(3.1416)));
  384.     
  385.     CalcPoint(&newPoint, hourRadius, centerPoint, clockRect, radians);
  386.  
  387.     FW_CLineShape line(centerPoint, newPoint);
  388.     line->SetPenSize(ff(3));
  389.     line->SetTransferMode(FW_kXOr);
  390.     line->Draw(gc);
  391. }
  392.  
  393. //----------------------------------------------------------------------------------------
  394. // CClockFacet::DrawMinuteHand
  395. //----------------------------------------------------------------------------------------
  396. void CClockFacet::DrawMinuteHand(FW_CGraphicContext *gc, 
  397.                                 const FW_CRect& clockRect, 
  398.                                 const FW_CPoint& centerPoint, 
  399.                                 Fixed minute)
  400. {
  401.     FW_CPoint newPoint;
  402.     Fixed minuteRadius = centerPoint.x - (centerPoint.x / 20);  // Make the minute hand longer than the hour hand
  403.  
  404.     // Divide the clock face into degrees.  (360 degrees divided by 60 minutes is 6 degrees per minute)
  405.     Fixed radians = ::FixDiv(minute * 6, ::FixDiv(ff(180), fl(3.1416)));
  406.  
  407.     CalcPoint(&newPoint, minuteRadius, centerPoint, clockRect, radians);
  408.  
  409.     FW_CLineShape line(centerPoint, newPoint);
  410.     line->SetPenSize(ff(2));
  411.     line->SetTransferMode(FW_kXOr);
  412.     line->Draw(gc);
  413. }
  414.  
  415. //----------------------------------------------------------------------------------------
  416. // CClockFacet::DrawSecondHand
  417. //----------------------------------------------------------------------------------------
  418. void CClockFacet::DrawSecondHand(FW_CGraphicContext *gc, 
  419.                                 const FW_CRect& clockRect, 
  420.                                 const FW_CPoint& centerPoint, 
  421.                                 Fixed second)
  422. {
  423.     FW_CPoint newPoint;
  424.     Fixed secondRadius = centerPoint.x - (centerPoint.x / 40);    // A nice sweeping second hand
  425.  
  426.     // Divide the clock face into degrees.  (360 degrees divided by 60 seconds is 6 degrees per second)
  427.     Fixed radians = ::FixDiv(second * 6, ::FixDiv(ff(180), fl(3.1416)));
  428.  
  429.     CalcPoint(&newPoint, secondRadius, centerPoint, clockRect, radians);
  430.  
  431.     FW_CLineShape line(centerPoint, newPoint);
  432.     line->SetTransferMode(FW_kXOr);
  433.     line->Draw(gc);
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // CClockFacet::UpdateAnalogClock
  438. //----------------------------------------------------------------------------------------
  439. void CClockFacet::UpdateAnalogClock(FW_CGraphicContext *gc, unsigned long tickCount)
  440. {
  441.     FW_CPoint centerPoint;
  442.     DateTimeRec time;
  443.     DateTimeRec lastTime;
  444.     
  445.      ::GetDateTime(&tickCount);
  446.     ::Secs2Date(tickCount, &time);
  447.     ::Secs2Date(fClockFrame->GetClockPart()->GetLastTime(), &lastTime);
  448.     
  449.     FW_CRect clockRect;
  450.     fClockFrame->GetFrameShapeBounds(&clockRect);
  451.         
  452.     centerPoint.x = (clockRect.right - clockRect.left) / 2;
  453.     centerPoint.y = (clockRect.bottom - clockRect.top) / 2;
  454.     
  455.     // Since we're called every second go ahead and update the second hand
  456.     this->DrawSecondHand(gc, clockRect, centerPoint, ff(lastTime.second));
  457.     this->DrawSecondHand(gc, clockRect, centerPoint, ff(time.second));
  458.  
  459.     if (lastTime.minute != time.minute)
  460.     {
  461.         this->DrawMinuteHand(gc, clockRect, centerPoint, ff(lastTime.minute));
  462.         this->DrawMinuteHand(gc, clockRect, centerPoint, ff(time.minute));
  463.         
  464.         this->DrawHourHand(gc, clockRect, centerPoint, ff(lastTime.hour), ff(lastTime.minute));
  465.         this->DrawHourHand(gc, clockRect, centerPoint, ff(time.hour), ff(time.minute));
  466.     }
  467. }
  468.  
  469. //----------------------------------------------------------------------------------------
  470. // CClockFacet::UpdateDigitalClock
  471. //----------------------------------------------------------------------------------------
  472. void CClockFacet::UpdateDigitalClock(FW_CGraphicContext *gc, unsigned long tickCount)
  473. {        
  474.     Str255 str;
  475.     ::IUTimeString(tickCount, TRUE, str);    
  476.  
  477.     FW_CString32 time;
  478.     time.ReplaceAll(str);
  479.         
  480.     FW_CRect clockRect;
  481.     fClockFrame->GetFrameShapeBounds(&clockRect);
  482.     
  483.     FW_CRectShape rectShape(clockRect);
  484.  
  485.     rectShape->SetForeColor(FW_kRGBWhite);
  486.     rectShape->Draw(gc);
  487.     
  488.     rectShape->SetShapeFill(FW_kFramed);
  489.     rectShape->SetForeColor(FW_kRGBBlack);
  490.     rectShape->Draw(gc);
  491.     
  492.     FW_CTextShape textShape(time);
  493.     textShape->SetFontName(FW_kSystemFont);
  494.     textShape->SetFontSize(ff(12));
  495.     textShape->Draw(gc, clockRect, FW_kFlushCenter);
  496. }
  497.  
  498.